﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace F_Test02
{
    public partial class Computer : Form
    {
        // This is the Computer class
        //
        public string Sumstr="";//输入的数字字符串
        double result; //计算结果

        public void Addstrings(string str)
        {
            Sumstr += str;
            lblShow.Text = Sumstr;
        }
      
        /*//写一个根据 中缀表达式转换为后缀表达式算法 计算函数表达式字符串的结果
        //算法思路：
        //1.根据"+"、"-"、"*"、"/" 、"="符号进行分割字符串
        //2.判断是否有两个数值
        //3.将中缀表达式转换为后缀表达式
        //4.计算后缀表达式
        //5.显示结果    
        //中缀表达式转换为后缀表达式*/

        /// <summary>
        /// 计算字符串表达式
        /// </summary>
        /// <param name="str"></param>
        public double Calculate(string str )
        {
            string str00 = str;
            // 每遇到一个运算符,前后插入空格,便于后续处理
            str = str.Replace("+", " + ");
            str = str.Replace("-", " - ");
            str = str.Replace("*", " * ");
            str = str.Replace("/", " / ");
            //Console.WriteLine(str01);

            string[] str01 = str.Split(' ');//分割字符串,存为字符串数组
            string[] str02 = Fransformed(str01);//转换为后缀表达式数组
            result = Compute(str02);//计算后缀表达式
            lblShow.Text = str00;

            return result;
        
        }
        private void bt_equals_Click(object sender, EventArgs e)
        {
            double result=0;
            try
            {
                result = Calculate(Sumstr);
                lblShow2.Text = "= " + result.ToString();
            }
            catch (Exception ex)    
            {
                MessageBox.Show(ex.Message);
            }
        
          
        }

        /// <summary>
        /// 将中缀表达式转换为后缀表达式
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string[] Fransformed(string[] str)
        {
            Stack<string> operatorStack = new Stack<string>();
            List<string> output = new List<string>();

            foreach (string token in str)
            {

                // 数字直接输出
                if (double.TryParse(token, out _))
                {
                    output.Add(token);
                }// 运算符入栈
                else if (token == "(")//左括号入栈
                {
                    operatorStack.Push(token);
                }
                else if (token == ")")//右括号出栈并输出
                {//弹出栈顶元素直到遇到左括号
                    while (operatorStack.Count > 0 && operatorStack.Peek() != "(")//栈顶元素不是左括号，则输出栈顶元素
                    {//弹出栈顶元素并输出
                        output.Add(operatorStack.Pop());
                    }
                    operatorStack.Pop();
                }
                else
                {//运算符出栈并输出
                    while (operatorStack.Count > 0 && GetPrecedence(operatorStack.Peek()) >= GetPrecedence(token))//栈顶元素优先级大于当前元素，则输出栈顶元素
                    {
                        output.Add(operatorStack.Pop());//弹出栈顶元素
                    }
                    operatorStack.Push(token);//当前元素入栈
                }
            }
            //将栈中剩余的运算符全部弹出并输出
            while (operatorStack.Count > 0)
            {
                output.Add(operatorStack.Pop());
            }

            return output.ToArray();
        }

        /// <summary>
        /// 获取运算符的优先级
        /// </summary>
        /// <param name="op"> 运算符 </param>
        /// <returns></returns>
        private static int GetPrecedence(string op)
        {
            switch (op)
            {
                case "+":
                    return 1;
                case "-":
                    return 1;
                case "*":
                    return 2;
                case "/":
                    return 2;

                default:
                    return 0;
            }
        }

        /// <summary>
        /// 计算后缀表达式
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static double Compute(string[] str)
        {
            Stack<double> stack = new Stack<double>();

            foreach (string token in str)
            {
                if (double.TryParse(token, out double num))
                {
                    stack.Push(num);
                }
                else
                {
                    double right = stack.Pop();
                    double left = stack.Pop();
                    switch (token)
                    {
                        case "+":
                            stack.Push(left + right);
                            break;
                        case "-":
                            stack.Push(left - right);
                            break;
                        case "*":
                            stack.Push(left * right);
                            break;
                        case "/":
                            stack.Push(left / right);
                            break;
                    }
                }
            }

            return stack.Pop();
        }




        public Computer()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void bt_clear_Click(object sender, EventArgs e)
        {
            Sumstr = "";
            lblShow.Text = Sumstr;
            lblShow2.Text = "";
        }

        private void bt_1_Click(object sender, EventArgs e)
        {
            Addstrings("1");
        }

        private void bt_2_Click(object sender, EventArgs e)
        {
            Addstrings("2");
        }

        private void bt_3_Click(object sender, EventArgs e)
        {
            Addstrings("3");
        }

        private void bt_4_Click(object sender, EventArgs e)
        {
            Addstrings("4");
        }

        private void bt_5_Click(object sender, EventArgs e)
        {
            Addstrings("5");
        }

        private void bt_6_Click(object sender, EventArgs e)
        {
            Addstrings("6");
        }

        private void bt_7_Click(object sender, EventArgs e)
        {
            Addstrings("7");
        }

        private void bt_8_Click(object sender, EventArgs e)
        {
            Addstrings("8");
        }

        private void bt_9_Click(object sender, EventArgs e)
        {
            Addstrings("9");
        }

        private void bt_0_Click(object sender, EventArgs e)
        {
            Addstrings("0");
        }

        private void bt_point_Click(object sender, EventArgs e)
        {
            Addstrings(".");
        }

        private void bt_add_Click(object sender, EventArgs e)
        {
            Addstrings("+");
        }

        private void bt_subtract_Click(object sender, EventArgs e)
        {
            Addstrings("-");
        }

        private void bt_multiply_Click(object sender, EventArgs e)
        {
            Addstrings("*");
        }

        private void bt_division_Click(object sender, EventArgs e)
        {
            Addstrings("/");
        }

        private void bt_delete_Click(object sender, EventArgs e)
        {
            //删除最后一个字符
            if (Sumstr.Length > 0)
            {
                Sumstr = Sumstr.Substring(0, Sumstr.Length - 1);
                lblShow.Text = Sumstr;
            }
        
        }
       
    }
}
